package application;

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;

import tools.EraserTool;
import tools.FreehandTool;
import tools.ObjectSelectorTool;
import tools.TextTool;
import tools.ToolList;
import tools.TwoEndShapeTool;
import tools.shapes.FilledOvalShape;
import tools.shapes.FilledRectangleShape;
import tools.shapes.LineShape;
import tools.shapes.OvalShape;
import tools.shapes.RectangleShape;

import java.net.*;

@SuppressWarnings("serial")
public class ObjectDraw5 extends JApplet
{
	// Components
	protected CanvasView canvas;
	protected ControlPanelView controlPanel;
	protected ToolBarView toolBar;
	protected ToolMenuView menuBar;
	protected ToolList toolList;
	protected boolean isApplet = false;
	protected String [] toolNames = new String [9];
	
	// Constructors
	public ObjectDraw5(boolean isApplet)
	{ 
	    this.isApplet = isApplet;
	    if (!isApplet)
	    {
	      init();
	    }
	  }

	  public ObjectDraw5()
	  {
	    /* invoked as Applet */
	    this(true);
	  }
	  
	  /**
	   * Invoked implicitly if MiniDraw is executed as an applet.  Otherwise, the
	   * constructor will explicitly call this method to initialize and display all 
	   * of the MiniDraw components. 
	   */
	  public void init() {
		toolNames[0] = "Freehand";
		toolNames[1] = "Line";
		toolNames[2] = "Object";
		toolNames[3] = "Rectangle";
		toolNames[4] = "FillRect";
		toolNames[5] = "Oval";
		toolNames[6] = "FillOval";
		toolNames[7] = "Text";
		toolNames[8] = "Eraser";
	    
		getContentPane().setLayout(new BorderLayout());
	    canvas = new CanvasView();
	    getContentPane().add(canvas, BorderLayout.CENTER);
	    controlPanel = createControlPanelView();
	    getContentPane().add(controlPanel, BorderLayout.SOUTH);
	    toolList = createToolList();
	    toolBar = new ToolBarView(toolNames, canvas);
	    getContentPane().add(toolBar, BorderLayout.WEST);
	    menuBar = new ToolMenuView(toolList);
	    getContentPane().add (menuBar, BorderLayout.NORTH);
	  }
	  
	  /************************init methods*****************/
	  
	  /**
	   * Initialize a new ControlPanelView
	   * 
	   * Simple factory method.  Requires the canvas to be initialized. 
	   * See ControlPanelView for more details. 
	  **/
	  protected ControlPanelView createControlPanelView() 
	    throws NullPointerException
	    {
		  if( canvas != null )
			  return new ControlPanelView(canvas);
		  else
			throw new NullPointerException( "Canvas not initialized." );
	    }
	  
	  /**
	   *  Configure tool list used for ToolBar and MenuBar construction.
	   *  
	   *  ToolList is initialized by adding several ToolControllers.  
	   *  ToolControllers extend the abstract action class allowing easy display of
	   *  the tool via a menu and a tool bar button.  More details are provided in
	   *  the ToolController documentation.
	  **/
	  protected ToolList createToolList()
	  {
		  ToolList actions = new ToolList();
		  
		  actions.add(
				  new ToolController("Freehand",
	  	                  "freehand drawing tool",
	  	                  canvas,
	  	                  new FreehandTool(canvas)));

		  actions.add(
				  new ToolController("Line",
						  "Line drawing tool",
						  canvas,
						  new TwoEndShapeTool(canvas, new LineShape())));
		  
		  actions.add(
				  new ToolController("Object",
						  "Object selecting tool",
						  canvas,
						  new ObjectSelectorTool(canvas)));
	  	
		  actions.add(
				  new ToolController("Rectangle",
						  "Rectangle drawing tool",
						  canvas,
						  new TwoEndShapeTool(canvas, new RectangleShape())));
		  
		  actions.add(
				  new ToolController("FillRect",
						  "Solid rectangle drawing tool",
						  canvas,
						  new TwoEndShapeTool(canvas, new FilledRectangleShape())));
		  
		  actions.add(
				  new ToolController("Oval",
						  "Oval drawing tool",
						  canvas,
						  new TwoEndShapeTool(canvas, new OvalShape())));
		  
		  actions.add(
				  new ToolController("FillOval",
						  "Solid oval drawing tool",
						  canvas,
						  new TwoEndShapeTool(canvas, new FilledOvalShape())));
		  
		  actions.add(
				  new ToolController("Text",
						  "Text entering tool",
						  canvas,
						  new TextTool(canvas)));
		  
		  actions.add(
				  new ToolController("Eraser",
						  "Eraser drawing tool",
						  canvas,
						  new EraserTool(canvas)));
		  return actions;
	  }
	  
	  /****************Class methods************************/
	  
	  /**
	   * Attempts to load an Image from the local disk.
	   * 
	   * Retrieving the current working directory varies whether the program was
	   * executed as an Applet or an Application.  Assumes that the images will be
	   * located at the top directory of the binary files.
	   * 
	   * @param fileName file name of the image relative to the current working
	   *                 directory
	   * @return new ImageIcon
	   */
	  protected ImageIcon getImageIcon(String fileName)
	  {
	    URL url;
		if(isApplet)
		{
			try
			{
				url = new URL(getCodeBase(), fileName);    
			}
			catch(MalformedURLException e)
			{
				return null;
			}
			return new ImageIcon( url );
	    }// end executed as applet
	    else
	    {
	    	return new ImageIcon( fileName );
	    }// end executed as application    
	  }// end protected ImageIcon getImageIcon( String )
	  
	  /* Main method  */
	  public static void main(String[] args)
	  {
		  JFrame frame = new JFrame();
		  frame.setTitle("ObjectDraw");
		  frame.getContentPane().setLayout(new BorderLayout());
		  frame.getContentPane().add(new ObjectDraw5(false), BorderLayout.CENTER);
		  frame.addWindowListener(new AppCloser());
		  frame.pack();
		  frame.setSize(600, 400);
		  frame.setVisible(true);
	  }
	  
	  /****< AppCloser >***********************************************************/

	  /**
	   * Inner class for terminating the application.
	   *
	   * When executed as an application, closing the window does not necessarily
	   * trigger application termination. This class catches the window closing
	   * event and terminates the application.
	   */
	  static class AppCloser extends WindowAdapter
	  {
		  public void windowClosing(WindowEvent e)
		  {
			  System.exit(0);
		  }
	  }// end static class AppCloser extends WindowAdapter
}
